<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  
  
  <link rel="shortcut icon" href="../img/favicon.ico">
  <title>Ⅱ. .NET Core JSON 的结构 - .NET JSON 源码分析</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700" />

  <link rel="stylesheet" href="../css/theme.css" />
  <link rel="stylesheet" href="../css/theme_extra.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
  
  <script>
    // Current page data
    var mkdocs_page_name = "\u2161. .NET Core JSON \u7684\u7ed3\u6784";
    var mkdocs_page_input_path = "Structure.md";
    var mkdocs_page_url = null;
  </script>
  
  <script src="../js/jquery-2.1.1.min.js" defer></script>
  <script src="../js/modernizr-2.8.3.min.js" defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script> 
  
</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
    <div class="wy-side-scroll">
      <div class="wy-side-nav-search">
        <a href=".." class="icon icon-home"> .NET JSON 源码分析</a>
        <div role="search">
  <form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" title="Type search term here" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="..">首页</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../Introduction/">Ⅰ. JSON 与 .Net Core JSON</a>
                    </li>
                </ul>
                <ul class="current">
                    <li class="toctree-l1 current"><a class="reference internal current" href="./">Ⅱ. .NET Core JSON 的结构</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#1-systemtextjson">1. System.Text.Json 的结构</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#public">public</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#internal">internal</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#2-systemtextjsonserialization">2. System.Text.Json.Serialization 的结构</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#public_1">public</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#internal_1">internal</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#3-systemtextjsonserializationconverters">3. System.Text.Json.Serialization.Converters 的结构</a>
    </li>
    </ul>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../Procedure/">Ⅲ. 序列化与反序列化的过程</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../Summary/">Ⅳ. 总结</a>
                    </li>
                </ul>
      </div>
    </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
        <a href="..">.NET JSON 源码分析</a>
      </nav>

      
      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href="..">Docs</a> &raquo;</li>
    
      
    
    <li>Ⅱ. .NET Core JSON 的结构</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <h1 id="ii-net-core-json">Ⅱ. .NET Core JSON 的结构</h1>
<p>在上一部分中，我们提到 .NET Core JSON 总共包含了 <code>System.Text.Json</code> 和 <code>System.Text.Json.Serialization</code> 两个命名空间。下面我们借助 UML 图来分析一下它们的结构。</p>
<p>后续讨论中，我们不专门区分类（class）与结构（struct）。</p>
<h2 id="1-systemtextjson">1. <code>System.Text.Json</code> 的结构</h2>
<h3 id="public">public</h3>
<p><code>System.Text.Json</code> 命名空间包含了 6 个类、10 个结构体和 4 个枚举（仅包括 public），下图展示了他们的关系。</p>
<p><img alt="System.Text.Json" src="../images/System.Text.Json.svg" /></p>
<ul>
<li><code>JsonDocument</code>：基于 <code>IDisposable</code> 建立了一个 JSON 的文档模型；</li>
<li><code>JsonElement</code>：表示 <code>JsonDocument</code> 中一个特定的 JSON 值；</li>
<li><code>JsonProperty</code>：表示 JSON 对象的单个属性（键值对）；</li>
<li><code>JsonSerializer</code>：提供了一系列序列化和反序列化的方法；</li>
<li><code>Utf8JsonReader</code>、<code>Utf8JsonWriter</code>：提供了一套用于读写 UTF-8 编码 JSON 文本的高性能 API。</li>
</ul>
<h3 id="internal">internal</h3>
<p><code>System.Text.Json</code> 还包括了一些私有类：
* <code>JsonClassInfo</code>：似乎用于保存类的相关信息；
* <code>ReadStack</code>、<code>WriteStack</code>……：貌似提供了一个读写栈的 API。</p>
<h2 id="2-systemtextjsonserialization">2. <code>System.Text.Json.Serialization</code> 的结构</h2>
<h3 id="public_1">public</h3>
<p><code>System.Text.Json.Serialization</code> 命名空间包含了 15 个类和 2 个枚举（仅包括 public），下图展示了他们的关系。</p>
<p><img alt="System.Text.Json.Serialization" src="../images/System.Text.Json.Serialization.svg" /></p>
<ul>
<li><code>JsonAttribute</code>：序列化属性的抽象基类；</li>
<li><code>JsonConverter</code>：提供了各类转换器（将对象、值转化为 JSON，或者将 JSOn 转化为对象、值）的抽象基类；</li>
<li><code>JsonConverter&lt;T&gt;</code>：从 <code>JsonConverter</code> 派生，提供了各类转换器的抽象基类，适用于非泛型或封闭式泛型类型；</li>
<li><code>JsonConverterFactory</code>：从 <code>JsonConverter</code> 派生，提供了各类转换器的抽象基类，适用于处理类型 <code>Enum</code> 或开放式泛型；</li>
<li><code>ReferenceHandler</code>：提供了处理引用的抽象基类；</li>
</ul>
<p>可以注意到这些公共类大多是一些抽象类，规定了序列化、反序列化过程中处理模式的框架，需要子类来实现。</p>
<p>通过 UML 类图可以看到，<code>JsonPropertyNameAttribute</code>、<code>JsonIgnoreAttribute</code> 等类继承自 <code>JsonAttribute</code>，详细定义了一些序列化属性。这里体现了面向接口编程的一些特点。</p>
<h3 id="internal_1">internal</h3>
<p><code>System.Text.Json.Serialization</code> 命名空间也包含了相当多的私有类：
* <code>ConverterList</code>：保存了内建转换器的列表；
* <code>JsonResumableConverter&lt;T&gt;</code>：从 <code>JsonConverter&lt;T&gt;</code> 派生，提供了可恢复的转换器的抽象基类，用于基于流的序列化 API。
* <code>JsonCollectionConverter&lt;TCollection, TElement&gt;</code>、<code>JsonDictionaryConverter&lt;T&gt;</code>、<code>JsonObjectConverter&lt;T&gt;</code>：从 <code>JsonResumableConverter&lt;T&gt;</code> 派生，分别提供了集合、字典、对象的转化器的抽象基类。</p>
<h2 id="3-systemtextjsonserializationconverters">3. <code>System.Text.Json.Serialization.Converters</code> 的结构</h2>
<p>到现在，我们还是没有看到 <code>JsonConverter</code> 类的具体实现……这些转换器被藏在了 <code>System.Text.Json.Serialization.Converters</code> 这个名字空间里面。这个名字空间里面提供了 58 个类、枚举，大部分都用 <code>internal sealed</code> 修饰，表明它们是密封好的私有类，此外还有少部分抽象类。</p>
<p>至此，转换器的结构已经形成了很复杂的一棵树，如下图所示：
<img alt="Convertors" src="../images/Convertors.svg" /></p>
<p>根据这样的结构，上层处理结构只需要调用 <code>JsonConverter</code> 类即可完成转换工作，而不需要关心转换的细节。</p>
<p>从类图上我们可以看到，转换器分为了普通模式（适用于非泛型或封闭式泛型类型）和工厂模式（适用于处理类型 <code>Enum</code> 或开放式泛型）两大类。普通模式尚且容易理解，来什么类型给什么转换器，但工厂模式（以及 .NET 中的开放式泛型）就稍微难懂一些。以 <code>List&lt;T&gt;</code> 为例，<code>T</code> 尚未确定，对于 <code>T</code> 的不同取值会需要不同的转换器，工厂模式即是将这个不确定的类型确定化，返回一个对应这个类型的转换器（“工厂”）。</p>
              
            </div>
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="../Procedure/" class="btn btn-neutral float-right" title="Ⅲ. 序列化与反序列化的过程">Next <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href="../Introduction/" class="btn btn-neutral" title="Ⅰ. JSON 与 .Net Core JSON"><span class="icon icon-circle-arrow-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <!-- Copyright etc -->
    
  </div>

  Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
      
        </div>
      </div>

    </section>

  </div>

  <div class="rst-versions" role="note" aria-label="versions">
    <span class="rst-current-version" data-toggle="rst-current-version">
      
      
        <span><a href="../Introduction/" style="color: #fcfcfc;">&laquo; Previous</a></span>
      
      
        <span style="margin-left: 15px"><a href="../Procedure/" style="color: #fcfcfc">Next &raquo;</a></span>
      
    </span>
</div>
    <script>var base_url = '..';</script>
    <script src="../js/theme.js" defer></script>
      <script src="../search/main.js" defer></script>
    <script defer>
        window.onload = function () {
            SphinxRtdTheme.Navigation.enable(true);
        };
    </script>

</body>
</html>
